三维场景概述

最后更新时间:2020年12月18日

功能介绍

MapGIS Mobile基于高性能的移动三维渲染引擎与C++三维内核,提供移动端全空间真三维应用功能,全面支持离线与在线的矢量、影像、DEM、栅格瓦片、模型(含M3D)、IGServer地图服务、第三方地图服务等各种数据,以及支持场景球面与平面模式等场景管理功能,提供场景漫游、地形贴合、多种场景覆盖物等多种功能,满足移动端真三维应用需求。【所有移动三维功能API由mapgis_ android_geoscene.jar提供】

MapGIS Mobile for Android移动三维开发平台提供了多种功能,当然这些功能的基础就是三维场景的展示,三维功能的展示都是依托于场景的显示,接下来学习三维场景展示的相关介绍。

1
离线三维矢量

开发者可通过该功能,实现移动端加载离线三维矢量数据。支持直接加载shp格式的离线矢量数据,须将数据拷贝到移动设备。

2
离线三维地形

开发者可通过该功能,实现移动端加载离线三维地形数据。支持直接加载tif格式的离线三维地形数据,须将数据拷贝到移动设备。

3
离线三维影像

开发者可通过该功能,实现移动端加载离线三维影像数据。支持直接加载tif等格式的离线三维影像数据,须将数据拷贝到移动设备。

4
离线三维模型

开发者可通过该功能,实现移动端加载离线三维模型数据。支持移动端加载常用的开放三维模型,如obj、ive、3ds等格式的三维模型数据。

5
IGServer矢量服务

开发者可通过该功能,实现移动端在三维场景中加载IGServer二维矢量服务地图,须通过MapGIS IGServer发布可用的二维矢量地图服务。

6
IGServer瓦片服务

开发者可通过该功能,实现移动端在三维场景中加载IGServer二维瓦片服务地图,须通过MapGIS IGServer发布可用的二维瓦片地图服务。

7
IGServer三维服务

开发者可通过该功能,实现移动端在三维场景中加载IGServer三维服务地图,须通过MapGIS IGServer发布可用的三维地图服务。

8
在线WMS服务

开发者可通过该功能,实现移动端在三维场景中加载在线WMS服务地图,可通过MapGIS IGServer或第三方发布可用的WMS服务。

9
在线TMS服务

开发者可通过该功能,实现移动端在三维场景中加载第三方在线TMS服务,须确保在线TMS服务可正常调用。

10
在线Google地图服务

开发者可通过该功能,实现移动端在三维场景中加载第三方在线Google地图服务,须确保在线Google地图服务可正常调用。

数据类型

MapGIS Mobile for Android三维开发平台提供多种类型的三维场景数据,如下图所示,后续会讲解每种数据的展示如何实现。

三维数据类型.png

基本原理

移动端三维场景展示与MapGIS桌面平台软件中场景展示的设计相对应,均通过地图文档—场景—图层来组织,采用一个场景视图控件(com.zondy.mapgis.android.sceneview.SceneView)作为容器装载三维场景,调用其相关接口就可加载三维场景地图。同时,移动端三维场景展示的与二维地图显示的原理也类似。

基本原理.png

场景中图层数据组织关系如下图所示:

数据图层组织关系.png

在场景视图中加载一个三维场景,通过各数据图层分别加载不同的数据,即通过三维矢量图层(VectorLayer3D)、三维地形图层(TerrainLayer3D)、地图引用图层(MapRefLayer)、三维模型图层(ModelCacheLayer3D)等加载对应的离线数据,包括MapGIS二三维数据(矢量、栅格、高程、M3D模型等数据)、倾斜摄影、点云数据等;通过服务图层(ServerLayer3D)加载各类在线地图数据,如IGServer发布的二维地图与三维地图服务、OGC服务、第三方公共地图服务如天地图、Google地图等。

功能接口

场景展示功能对应API程序包为com.zondy.mapgis.android.sceneview中的核心类SceneView,以及com.zondy.mapgis.core.scene包中的Scene、Layer3D、GroupLayer3D、ServerLayer3D、VectorLayer3D、TerrainLayer3D、ModelCacheLayer3D等,核心接口如下所示:

接口 说明
SceneView.setScene() 设置场景
SceneView.setSceneAsync() 设置场景(异步方法)
Scene.addLayer() 在场景中添加三维图层
Layer3D.setDriverType() 设置图层驱动类型
Layer3D.setSRSByString() 设置图层参考系

基本流程

1

数据准备


实现三维场景展示之前,首先需要准备需显示的三维数据,以离线矢量数据为例,MapGIS Mobile支持直接加载.shp格式矢量数据,用户可以准备一份shp数据,然后直接拷贝到移动设备的存储中。

2

创建工程


以Android Studio作为开发工具,创建工程。

创建项目.png

项目创建完成之后,需要为应用程序添加需要的移动设备资源使用权限。实现三维场景展示功能,首先需要进行MapGIS的环境初始化、授权操作,加载离线或者在线地图,所以需要应用具备读/写手机存储的权限、联网权限、读取手机状态的权限。在“AndroidManifest.xml”程序清单文件中编写对应权限标签。

<!-- 允许应用程序向外部存储写入数据 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 允许应用程序读取外部存储数据 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 允许对移动存储安装和卸载文件系统 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 允许应用程序只读访问手机状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 允许应用程序访问网络,可能产生GPRS流量 -->
<uses-permission android:name="android.permission.INTERNET" />

说明:在应用程序的targetSdkVersion版本大于等于23,手机的Android系统版本大于等于6.0时,对于读写手机存储、读取手机状态等危险权限,需要在Java代码中通过代码来动态申请权限。

3

引入二次开发库

项目创建完成后,在实现三维场景功能实现之前,需要向工程中导入MapGIS的开发库。从云生态圈的开发世界中获取MapGIS Mobile for Android二次开发包,其中libs文件夹中的文件就是实现MapGIS移动GIS功能需要的具体开发库,包括jar包和so库两部分,使用时需将其引入到项目中。libs下的开发库如下图所示:

开发库.png

对于三维功能,主要使用mapgis _ android_ base.jar(用于环境初始化、授权)、mapgis _ android_ geoscene.jar(三维核心库)、mapgis _ android_geomap.jar(用于二维地图相关功能)三个开发包。将所需要的jar包与对应的so库导入到工程中。

(1) 导入jar包:切换工程目录结构为“Project”模式,将jar包拷贝到工程的“app\libs”目录下。添加完成之后,选择加入的jar包,右键单击,在弹出的菜单中选择“Add As Library”,弹出“Create Library”对话框,选择app模块,点击“OK”即可。等待项目同步更新完成,查看当前module中的“build.gradle”脚本文件,发现其中在dependencies标签中增加了jar的依赖,到此完成jar包的导入。

导入jar包.png

(2) 导入so库:首先将SDK中libs目录下的armeabi、armeabi-v7a、arm64-v8a文件夹拷贝到模块module的libs目录下,可根据需要剔除不需要的so库。如果已有armeabi和armeabi-v7a目录,则直接将*.so库文件复制到对应的目录中。

导入so库.png

然后打开对应module下的build.gradle脚本文件,在android标签中,添加如下代码,完成后sync同步工程即可。

sourceSets {
    main {
        jniLibs.srcDirs = ['libs'];
    }
}

4

环境初始化与请求授权

要使用MapGIS移动平台提供的功能,导入开发库后,还需要初始化MapGIS环境、请求移动端授权,这样GIS功能才能得以使用。移动开发授权功能对应的API程序包为com.zondy.mapgis.environment(10.3版本:com.zondy.mapgis.android.environment),使用环境类(Environment)的接口方法实现。

在工程中展开src的目录,打开MainActivity.java文件,先获取移动设备SD卡上放置地图数据文件的路径,然后调用Environment的initialize()进行环境初始化,调用requestAuthorization()请求授权。使用MapGIS Mobile提供的功能接口之前,首先必须进行环境初始化和授权验证。

initialize(java.lang.String strRootPath, Context context)
环境初始化,必须在使用SDK各组件之前调用,会自动建立根目录结构
requestAuthorization(Context context,Environment.AuthorizeCallback callback) 
请求授权

说明:调用initialize()进行环境初始化,必须在使用SDK各组件之前调用,会自动建立根目录结构。

核心代码如下:

//环境目录路径
String strRootPath = android.os.Environment.getExternalStorageDirectory().getPath() + "/MapGISSample/";
//环境初始化,必须在使用SDK各组件之前调用,会自动建立根目录结构
Environment.initialize(strRootPath, getApplicationContext());
//请求授权
Environment.requestAuthorization(this, new Environment.AuthorizeCallback() {
    @Override
    public void onComplete() {
        System.out.println("授权完成");
    }
});

5

创建场景视图控件

在界面布局文件中添加一个场景视图控件(SceneView)。展开工程中的res/layout目录,编辑activity_main.xml文件,初始化加载一个SceneView视图(com.zondy.mapgis.android.sceneview.SceneView)并设置其ID、高、宽属性。

界面布局.png

代码如下:

<com.zondy.mapgis.android.sceneview.SceneView
    android:id="@+id/sceneView"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</com.zondy.mapgis.android.sceneview.SceneView>

添加场景视图控件之后,可以跳过接下来的步骤6,不编写场景加载代码,直接调试运行程序,同样能够看到三维场景视图,默认添加了地球影像,对场景中三维球进行用于显示的底图渲染。

6

编码实现场景展示

打开工程中src下的MainActivity.java文件,在请求授权成功回调函数中编写加载离线shp矢量数据的代码,完整代码如下所示:

public class MainActivity extends AppCompatActivity {

    //定义场景视图、场景对象
    private SceneView sceneView;
    private Scene scene;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //实例化场景视图
        sceneView = findViewById(R.id.sceneView);

        //环境目录路径
        String strRootPath = android.os.Environment.getExternalStorageDirectory().getPath() + "/MapGISSample/";
        //环境初始化,必须在使用SDK各组件之前调用,会自动建立根目录结构
        Environment.initialize(strRootPath, getApplicationContext());
        //请求授权
        Environment.requestAuthorization(this, new Environment.AuthorizeCallback() {
            @Override
            public void onComplete() {
                System.out.println("授权完成");

                VectorLayer3D vectorLayer3D = new VectorLayer3D();
                //为图层设置名称
                vectorLayer3D.setName("离线矢量数据");
                //为图层设置驱动类型(OGR数据驱动.用于离线矢量数据的读取)
                vectorLayer3D.setDriverType(DriverType.Driver_Type_OGR);
                //为图层设置URL
                vectorLayer3D.setURL(android.os.Environment.getExternalStorageDirectory().getPath() + "/MapGISSample/Scene/haiyang/haiyang.shp");

                //实例化场景、三维矢量图层
                scene = new Scene();
                //为场景添加图层
                scene.addLayer(vectorLayer3D);

                //为场景视图设置无光照模式
                sceneView.setSunLightingMode(SunLightingMode.NONE);
                //为场景视图设置场景
                sceneView.setSceneAsync(scene, new SceneView.SceneFinishCallback() {
                    @Override
                    public void onDidFinish(boolean b) {
                        if (b) {
                            Toast.makeText(MainActivity.this, "场景加载成功", Toast.LENGTH_SHORT).show();
                        } else {
                            Toast.makeText(MainActivity.this, "场景加载失败", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            }
        });
    }
}

7

调试运行、授权认证

单击菜单栏上的Run|Run ‘app’,或者工具栏上的 图标,在弹出的对话框中选择目标设备(模拟器或者真机),单击“OK”按钮,即可将项目安装到移动设备上。

运行设备选择.png

将项目安装到模拟器或者手机上,并运行。若初次运行基于MapGIS Mobile开发的app,将在app中弹出对话框进行授权认证,许可认证后的移动端设备再次运行使用此app则不会再弹框认证。

例如,在真机上运行app,确保地图数据已经拷贝到手机的SD卡目录下,初次运行时弹出对话框进行授权认证,输入有效的司马云开发者账号、密码,许可认证成功后进入场景展示界面。

0110授权认证.jpg 0111场景展示.jpg